<?php

namespace common\helpers;

use Yii;
use common\models\base\Project;

class RedisHelper
{
    /**
     * 根据ID获取项目信息
     *
     * @param int $id
     * @return bool|mixed
     */
    public static function getProjectById(int $id = 0)
    {
        // 获取key
        $key = self::getProjectKey($id);

        if (!Yii::$app->redis->exists($key)) {
            // 查询项目数据
            $project = Yii::$app->services->project->findById($id);
            if ($project) {
                self::setProject($project);
            } else {
                return false;
            }
        }

        return json_decode(Yii::$app->redis->get($key), true);
    }

    /**
     * 设置项目数据
     *
     * @param Project $project
     */
    public static function setProject(Project $project): void
    {
        // 获取key
        $key = self::getProjectKey($project->id);
        $data = $project->attributes;
        Yii::$app->redis->set($key, json_encode($data));
    }

    /**
     * 获取项目key
     *
     * @param int $id 项目ID
     * @return string
     */
    public static function getProjectKey(int $id = 0)
    {
        return Yii::$app->params['redis.project.list'].$id;
    }

    /**
     * 加锁
     * @param string $key 要限制的用户或订单唯一key值 （$key='redis_key_name：'.'订单id或其他本次锁的唯一值';）
     * @param int $expire 锁有效期，默认是有1秒
     * @param int $scene 场景 1、默认 2、处理事务限制
     * @return bool
     */
    public static function lock(string $key, int $expire=0, int $scene = 1): bool
    {
        $rate = 1000;
        $timeStart = microtime(true) * $rate;
         while (true) {
             $expire = $expire <=0 ? 1 : $expire;
             $lock_result = Yii::$app->redis->set($key, "lock", "nx", "ex", $expire);
             if ($lock_result) {
                 break;
             }
             // 事务处理
             if ($scene == 2) return false;

             $timeEnd = microtime(true) * $rate;
             if ($timeEnd - $timeStart > 10 * $rate) {
                 //add log error
                 return false;
             }
         }
         return true;
    }

    /**
     * 解锁
     * @param string $key
     */
    public static function unlock(string $key): void
    {
        Yii::$app->redis->del($key);
    }
}